home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-03-15 | 72.2 KB | 1,978 lines |
- ============================================================================
- Errata (16 May 1997)
- for correcting
- The Inform Designer's Manual, 3rd Ed. (4 September 1996)
- ============================================================================
-
- In February I published a draft list of errata, and here is the
- final list: new or altered corrections (since the draft, that
- is) are marked with asterisks in the margin.
-
- If these corrections are made then the manual becomes fully up to date
- with state-of-the-art Inform, i.e., Inform 6.13 and library 6/5.
- The primary version of the manual -- the TeX source code -- I've
- updated myself.
-
- Conversions should please note on their title pages that these errata
- have been absorbed, if they have been. For example, Stephen van
- Egmond's plain text copy might begin
-
-
- The Inform Designer's Manual
-
- by Graham Nelson
-
- Third edition
-
- 4 September 1996
-
- as updated 16 May 1997
-
- (note: the update date is the date of this errata list, not the date
- when the corrections were actually made by Stephen or whoever).
-
- What has been changed? Firstly there are a few dozen tiny mistakes,
- mostly typographical but some actually changing the meaning of the
- text. Secondly the manual reflects improved facilities in Inform
- for grammar, for enterable objects and for touchability rules, as
- well as subtle changes brought on by these. Thirdly a few passages
- have been clarified, usually at somebody's request. Fourthly
- almost all the exercise solutions have been tidied up and debugged.
- (For some months the "Museum of Inform" example game has contained
- much better coded solutions to the exercises than the manual gave.)
-
- I am especially indebted to Miron Schmidt for combing through the
- manual with infinite patience; and to several of the galley-slaves
- who spotted mistakes while reformatting, particularly Allison Weaver
- and Christopher Madsen. I would also like to acknowledge the
- trouble taken by Torbj|rn Andersson, Timothy Buege, Kevin Bracey,
- Linards Ticmanis, Anson Turner, Lucian Smith and above all
- Charles Briscoe-Smith in commenting on and adding to the draft errata.
-
-
- Graham Nelson
- 16 May 1997
-
- [MORE]
-
- References mainly given to page numbers in the TeX typeset original
- (4 September 1996) but note that Stephen van Egmond's plain text copy
- (11 October 1996) uses the same pagination and is easier to search.
- Italics below are written _thus_. The notation \S indicates
- a section sign. Text in a typewriter-style font is written between
- vertical strokes |thus|.
-
- Exercise, book and section numbering is unchanged: thus the old
- exercise 63 is still called exercise 63 in the corrected version,
- and so on.
-
-
- Part I -- All alterations except those to exercise solutions
- and to the list of library messages
- ==================================================
-
-
- detailed contents of section 28:
- * replace "which applies to other people as well;" with
- * "touchability is stricter than scope;"
-
- contents: Change the title of section 3.14 from
- * "Footnote on common vs. individual objects"
- * to
- * "Footnote on common vs. individual properties"
-
- p.6 The contents have the order of the appendices juggled. The
- correct sequence of A7, A8, A9 is:
-
- A7 Library-defined objects and routines
- A8 Library actions
- A9 Library message numbers
-
- p.7 After "...becoming someone else in mid-game." and before
- "The world-model includes...", insert the sentence "It can be
- configured to languages other than English."
-
- p.8 Alter "with a line reading just |...|"
- * to "with a line reading just ``|...|''", i.e., put the ellipsis
- * in quotation marks.
-
- p.8 Delete first "from" in "To keep from Book Two from ...".
-
- p.8 Delete the sentence "There is also a 'Shell' game ... anyway."
-
- p.8 Replace "The best source for Inform..." with "The Internet
- * source for Inform..." and change the sentence giving the ftp
- * directory to:
- *
- * Inform can be found at:
- * |ftp://ftp.gmd.de/if-archive/infocom/compilers/inform6|
-
- p.8 Delete the passage
-
- Another useful resource is the Inform home page on the `World
- Wide Web', currently maintained by Gareth Rees at:
- |http://www.cl.cam.ac.uk/users/gdr11/inform|
-
- and replace with
-
- Another useful resource is the Inform 6 home page on the `World
- Wide Web', which includes Gareth Rees's `Alice' tutorial,
- located at:
- |http://www.gnelson.demon.co.uk/inform.html|
-
- p.9 Rewrite the sentence
-
- This manual describes Inform release 6.04 (or later), using
- library release 6/2 (or later). Inform 6.01 to 6.03 and
- library 6/1 are very similar but Inform 5.5 and 5/12 very
- different.
-
- as
-
- * This manual describes Inform release 6.13 (or later), using
- * library release 6/5 (or later). Earlier Inform 6 compilers and
- * libraries are very similar but Inform 5.5 and 5/12 are very
- * different.
-
- p.9 Correct "So there are three `companion volumes'." to
- "So there are four `companion volumes'." At the end of this
- paragraph add the sentence
-
- _The Inform Translator's Manual_ describes how to write a
- language definition file for games which speak languages
- other than English.
-
- p.10 Correct the signing-off date to May 1997.
-
- p.18 Replace "One such operator is =:" with "One such operator is
- `set equals':"
-
- p.20 Remove "(there can be any number from none up to 7)". Instead
- add a new sentence after this one, reading:
-
- Usually, there can be any number of arguments from none up to 7,
- though a limit of 3 applies if Inform has been told to compile
- an early-model story file (see \S 31 for details).
-
- p.21 To the end of the text about |or|, continue with the following:
-
- * For example
- * | if (player in Forest or Village or Building) ...|
- * often makes code much clearer than writing three separate conditions
- * out; or
- * | if (x > 100 or y) ...|
- * can be convenient to check whether |x| is bigger than the minimum of
- * 100 or |y|.
-
-
- p.25 (foot of page) replace "...is deferred until \S 3." with
- "...is deferred until \S 3.4."
-
- p.27 Replace
-
- But there is always an escape. One drastic solution is to
- return from the current routine, in which case any loops are
- forgotten about. Another is to use |jump| (see later on)
- to run away. But the tidiest solution is to execute the
- statement |break|, which causes execution to "break out of"
- the current innermost loop or |switch| statement: it can
- be read as "finish early".
-
- with
-
- But there is always an escape. One way is to |return| from
- the current routine. Another is to |jump| to a label outside
- the loop (|jump| will be covered in \S 1.13 below). It's
- neater to use the statement |break|, which causes execution to
- "break out of" the current innermost loop or |switch| statement:
- it can be read as "finish early". All these ways out are
- entirely "safe", and there is no harm in leaving a loop only
- half-done.
-
- p.31 The first line of the examples on accents should read:
-
- * print "Les @oeuvres d'@Aesop en fran@ccais, mon @'el@`eve!";
-
- (The previous macaronic version was a sort of unfunny joke)
-
- p.31 For "Arvo Part", read "Arvo P@:art", that is, place a double-dot
- accent over the "a" in "Part".
-
- p.34 At the end of 1.14, after the table of printing rules,
- insert:
-
- * Note that |(the)| in lower case does something different from |(The)|
- * with an upper case T. This is very unusual! (Directive names,
- * which will turn up in \S 2, variable names and so on are allowed to
- * use upper case and the case is simply ignored, so that |fRoG|
- * means the same as |frog|. But statement keywords, like |print|
- * or |(name)|, have to be in lower case -- except for |(The)|.)
-
- and then insert a paragraph break so that the sentence starting
- "To create a new rule..." is now a paragraph in its own right.
-
- p.36 (closing words of section 1) Change "See \S 2 for details."
- to "See \S 2.5 for details."
-
- p.39 In "To recapitulate, Inform provides four kind of array in all:"
- "kind" should be "kinds".
-
- p.39 (just after the |primes| array) "is is a word array" should
- read "is a word array".
-
- p.39 An invisible mistake: ``text buffers'' (in the Frank Booth
- paragraph) should be index-marked, but in the TeX source it
- isn't, because of a mistype.
-
- p.40 Replace "There are more efficient ways to shuffle the pack."
- with "The example code shuffles the pack in a simple way, but
- there are more efficient methods."
-
- p.43 Replace
- * |parse_buffer-->(n*2 - 2)|
- * with
- * |parse_buffer-->(n*2 - 1)|
-
- p.44 Remove the sentence "The point has already been made that
- Inform's routines satisfy all the philosophical criteria to
- be called objects." (Who wrote this pompous drivel?)
-
- p.47 In the syntax of the Object directive, exchange <name> and
- <arrows>. Thus it should read
-
- Object <arrows> <name> "textual name" <parent>
-
- Similarly exchange notes 1. and 2. explaining what these are.
- Thus note 1. should now start "The <arrows> ..." and note 2.
- should now start "The <name> ...". (This should correct what
- Miron Schmidt was kind enough to call "an outright lie".)
-
- p.55 Delete "an" from
- * "one of the four kinds of an object"
-
- p.55 At the end of the "For example, |print kestrel.flying_strength|
- paragraph, add the sentence:
-
- (You can see all the messages being sent in a game as it runs
- with the debugging verb "messages": see \S 30 for details.)
-
- p.56 "or |nothing| if it wasn't sent from |Object|" should read
- "or |nothing| if it wasn't sent from an |Object|".
-
- p.62 Change the title of section 3.14 from
- * "Footnote on common vs. individual objects"
- * to
- * "Footnote on common vs. individual properties"
-
- p.62 Replace the entire footnote (that is, the whole text of section
- 3.14, though the title should remain) with the following:
-
- <triangle> <triangle> The properties used in the sections above
- are all examples of ``individual properties'', which some objects
- provide and others do not. There are also ``common properties''
- which, because they are inherited from the class |Object|, are
- provided by every member of |Object|.
-
- * An example is |capacity|. The |capacity| can be read for an
- * ordinary game object (say, a crate) even if it doesn't specify a
- * |capacity| for itself, and the resulting ``default'' value will
- * be 100. However, this is only a very weak form of inheritance --
- * you can't change the crate's |capacity| value and the condition
- * |crate provides capacity| evaluates to |false|.
-
- The properties defined by the Inform library, such as
- |capacity|, are all common: mainly because common properties
- are marginally faster to access and marginally cheaper on memory.
- * Only 62 are available, of which the library uses up 48.
- * Individual properties, on the other hand, are practically
- * unlimited. It is therefore worth declaring a common property only
- * in those cases where it will be used very often in your program.
- * You can declare common properties with the directive:
-
- |Property| <name>|;|
-
- which should be made after the inclusion of "Parser" but before
- first use of the new name. The class |Object| will now
- pass on this property, with value 0, to all its members. This
- so-called ``default value'' can optionally be specified. For
- example, the library itself makes the declaration
-
- |Property capacity 100;|
-
- which is why all containers in a game which don't specify any
- particular |capacity| can hold up to 100 items.
-
- p.64 In the paragraph ending "on-line documentation.", add a new
- final sentence:
-
- Note however that a filename can contain spaces if it is written
- in double-quotes.
-
- p.65 Replace "set these switches" (top of page) with:
-
- * set these switches; or unset any switch preceded by a tilde |~|.
- * (For example, |-a~bc| sets |a|, unsets |b| and sets |c|.)
-
- p.65 under "|+<name>=<filename>|", alter "the filename for a directory"
- * to "one or more filenames of directories, separated by commas".
-
- p.65 Add the following to the end of the first paragraph in section
- 4.2:
-
- (The rules for how Inform interprets |"filename"|
- vary from machine to machine: run Inform with the |-h1| switch
- for information.) Note that you can write
-
- |Include ">shortname";|
-
- to mean "the file called |"shortname"| which is in the same
- directory that the present file came from". This is convenient
- if all the files making up the source code of your game are
- housed together.
-
- p.67 In the code example beginning "For example, |Ifndef VN_1601|"
- and the sentence after it, correct 1601 to 1610 and 6.01 to 6.10.
-
- p.69 Add the switches:
-
- * |d2 contract double spaces after exclamation and question
- marks, too|
-
- * |g2 traces calls to all functions|
-
- * |E2 Macintosh MPW-style error messages|
-
- and correct the -g switch entry to
-
- * |g traces calls to functions (except those in the library)|
-
- p.70 The reference to \S 4.5 in the entry under the |M| switch
- should be to \S 4.3.
-
- p.73 "If this limit is passed, the error" should read "If this limit
- is passed, Inform generates the error".
-
- p.74 In "one syntax mistake threw Inform off the right track, so
- that continued not to know" insert "it" between "that" and
- "continued".
-
- p.77 Delete one of the two identical "'Ifnot' without..." lines
- listed just under "8. Conditional compilation".
-
- p.77 Delete one of the two dollar signs $ in the code line
-
- Iftrue #strings_offset==$$4a50;
-
- p.77 Delete one of the two "must"s in the third line under
- "9. Miscellaneous".
-
- p.80 Replace:
-
- * For instance, ordinarily ``take'', ``get'', ``carry'' and
- * ``hold'' are one single Inform verb, but this directive
- * could split off ``carry'' and ``get'' from the other two.
- * The warning would arise if one tried to split off ``take''
- * and ``drop'' together, which come from different original
- * Inform verbs.
-
- with:
-
- * For instance, ordinarily ``examine'', ``watch'', ``check'' and
- * ``describe'' are one single Inform verb, but this directive
- * could split off ``examine'' and ``watch'' from the other two.
- * The warning would arise if one tried to split off ``examine''
- * and ``search'' together, which come from different original
- * Inform verbs.
-
- p.82 (foot of page) The reference to \S 4 should be to \S 4.3.
-
- p.89 "the idea is clear enought" should read "the idea is clear
- enough".
-
- p.93 ThrowAt occurs twice in the list of group 3 actions.
- * Delete the first occurrence.
-
- p.98 After the sunlight object code example, add the sentence:
-
- (The |^| symbol in |"sun^s"| means an apostrophe, so the
- word is "sun's".)
-
- section 14 Add a new second and third paragraph:
-
- * If the player gets into a |container| and then closes it, the
- * effect is like being in a different location. (Unless the container
- * has the |transparent| attribute and is therefore see-through.)
- * The interior may be dark, but if there's light to see by, the
- * player will want to see some kind of room description. In any case,
- * many enterable objects ought to look different from inside or on
- * top. Inside a vehicle, a player might be able to see a steering
- * wheel and a dashboard, for instance. On top of a cupboard, it
- * might be possible to see through a skylight window.
-
- * For this purpose, any |enterable| object can provide a property
- * called |inside_description|, which can be a string or a routine
- * to print one, as usual. If the exterior location is still
- * visible, then the "inside description" is added to the
- * normal room description, and otherwise it becomes that
- * description. As an extreme example, suppose that the player
- * gets into a huge cupboard, closes the door behind her and
- * then gets into a plastic cabinet inside that. The resulting
- * room description might read like so:
- *
- * _The huge cupboard_ (in the plastic cabinet)
- * It's a snug little cupboard in here, almost a room in itself.
- *
- * In the huge cupboard you can see a pile of clothes.
- *
- * The plastic walls of the cabinet distort the view.
- *
- * The second line is the |inside_description| for the huge
- * cupboard, and the fourth is that for the plastic cabinet.
-
-
- p.116 "...overlap much more with Chapter ***" should read
- "...overlap much more with Chapter V".
-
- p.118 (in References) Delete the bulleted sentence beginning
- "|orders| and |grammar| are newly introduced..."
-
- section 17 The definitions for light are slightly altered and
- now read:
-
- * An object `offers light' if:
- * it itself has the |light| attribute set, or
- * any of its immediate possessions `have light', or
- * it is see-through and its parent offers light;
- * while an object `has light' if:
- * it currently has the |light| attribute set, or
- * it is see-through and one of its immediate possessions
- * has light, or
- * any of the things it ``adds to scope'' (see Chapter V) have light.
-
- p.122 Top line: replace the word "alternatively" with "also".
- Delete the entire next sentence: "Alternatively because an object
- can't have both a |timer| and a |daemon| going at the same time."
-
- p.122 Replace
-
- 'Each turn' is entirely separate from daemons and timers.
- Although an object can't have both a timer and a daemon at the
- same time, it can have an |each_turn| at the same time, and
- this is quite useful, especially to run creatures.
-
- with
-
- 'Each turn' is especially useful to run creatures which stay
- in one room and are only active when the player is nearby.
-
- p.132 (second triangle-marked paragraph) "because haven't got
- default values" should be "because they haven't got default
- values".
-
- p.134 (references to section 22)
- * Delete the reference to "pluralobj.h" (it's now incorporated
- * into the library).
-
- p.133 (top of page) The reference to \S A8, in the paragraph
- beginning "The |Jump| action...", should to be \S A9.
-
- p.136 Replace the paragraph:
-
- The indefinite article for an object is held in the property
- |article| and is assumed to be `a' if none is declared.
- That means that if the short name starts with a vowel, you need
- to set it to `an'. But article offers much more amusement:
-
- with:
-
- Inform tries to work out the right indefinite article for
- any object automatically. In English-language games, it uses
- `an' when the short name starts with a vowel and `a' when it
- does not (unless the name is plural, when `some' is used
- in either case). You can override this by setting |article|
- yourself. Here are some possibilities:
-
- p.136 Delete the words:
-
- , in case, let us say, "a pregnant mouse" has to change to
- "some mice"
-
- p.136 After the articles discussion, and just before the paragraph
- beginning "The short name of an object...", add two new
- paragraphs. First an ordinary one in running text:
-
- A single object whose name is plural, such as "grapes"
- or "marble pillars", should be given the attribute
- |pluralname|. As a result the library might say, e.g.,
- "You can't open those" instead of "You can't open that".
- It also affects the pronoun "them" and makes the usual
- indefinite article "some".
-
- Second, immediately following, a new triangle-marked
- paragraph:
-
- You can give |animate| objects the attributes |male|, |female|
- or |neuter| to help the parser understand pronouns properly.
- |animate| objects are assumed to be male if you set neither
- alternative.
-
- p.139 (in the numbered small print, mid-page, point 3) delete the
- second "then" (there are two "then"s in a row, one bold-face,
- the other Roman).
-
- p.139 (paragraph before Exercise 51) Reference to \S A9 should be
- to \S A7.
-
- p.143 The word "catachrestic" is correctly spelt in the text,
- but incorrectly spelt "catchrestic" in the index mark.
-
- p.144 After the sentence "Remember that the dictionary only has
- 9-character resolution." add "(And only 6 if Inform has been
- told to compile an early-model story file: see \S 31.)"
-
- p.146 (start of exercise 63) "There is no problem with a calling"
- should read "There is no problem with calling"
-
- p.148 Replace the sentence
-
- The simplest way to do this is just to put "crowns" in their
- |name| lists, and this works perfectly well most of the time.
-
- with:
-
- Putting the word |"crowns"| in their |name| lists is not quite
- right, because the parser will still think that ``crowns'' might
- refer to a specific item. Instead, put in the word |"crowns//p"|.
- The |//p| marks out the dictionary word "crowns" as one that
- can refer to more than one game object at once. (So that
- you shouldn't set this for the word "grapes" if a bunch of
- * grapes was a single game object; you should give that object
- * the |pluralname| attribute instead.) For example the |GoldCoin|
- class would read:
-
- |Class GoldCoin
- with name "gold" "coin" "coins//p",
- short_name "gold coin",
- plural "gold coins";|
-
- and now when the player types ``take coins'', the parser
- interprets this as ``take all the coins within reach''.
-
- p.148 In the immediately following double-triangle paragraph, replace
- the opening sentence and next eight words:
-
- But it isn't ideal, because ... available crowns. So the
- complicated (but better) way is to
-
- with:
-
- The only snag is that now the word |"coins"| is marked as
- |//p| everywhere in the game, in all circumstances. Here is
- * a more complicated way to achieve the same result, but
- * strictly in the context of these objects alone. We need to
-
- p.149 Change the list of equal verbs from
-
- "take" = "get" = "carry" = "hold"
-
- to
-
- "take" = "carry" = "hold"
-
- p.151 At the very top of the page, i.e. after the sample grammar
- at the foot of p.150 and before the words "Each line of grammar"
- insert the sentence:
-
- (You can look at the grammar being used in a game with the
- debugging verb "showverb": see \S 30 for details.)
-
- p.151 In the double-triangle section, replace the opening sentence:
-
- "As mentioned above, the parser thinks "take" and "get"
- are exactly the same."
-
- with:
-
- Since this book was first written, the library has been
- improved so that "take" and "get" each have their own
- independent grammars. But for the sake of example,
- suppose they share the grammar written out above.
-
- p.151 After the paragraph in which XyzzySub is written out,
- add a new single-triangle paragraph:
-
- Finally, the line can end with the word |reverse|.
- This is only useful if there are objects and numbers
- in the line are parsed in the wrong order. An example
- from the library's grammar:
-
- |Verb "show" "present" "display"
- * creature held -> Show reverse
- * held "to" creature -> Show;|
-
- The point is that the |Show| action expects the first
- parameter to be an item, and the second to be a person.
- When the text ``show him the shield'' is typed in, the
- parser must reverse the two parameters ``him'' and
- ``the shield'' before causing a |Show| action. On the other
- hand, in ``show the shield to him'' the parameters are in
- the right order already.
-
- p.153 (foot of page) After the first paragraph on prepositions,
- and before the triangle-marked second paragraph, insert
- the (ordinary) paragraph:
-
- It often happens that several prepositions really mean
- the same thing for a given verb: "in", "into" and "inside"
- are often equally sensible. As a convenient shorthand
- you can write a series of prepositions with slash marks |/|
- in between, to mean "one of these words". For example:
-
- | * noun "in"/"into"/"inside" noun -> Insert|
-
- (Note that |/| can only be used with prepositions.)
-
- p.154 Add a new token to the table, just before [special]:
-
- [topic] any text at all
-
- p.157 Add a new paragraph just before the one explaining [special]:
-
- [topic] This token matches as much text as possible.
- It should either be at the end of its grammar line, or
- be followed by a preposition. (The only way it can fail
- to match is if it finds no text at all.) The library's
- grammar uses this token for topics of conversation and
- topics looked up in books (see \S\S 15, 16), hence the
- name. The parser ignores the text for now (your own code
- will have to think about it later), and simply sets
- the variables |consult_from| to the first word of the
- matched text and |consult_words| to the number of words.
-
- p.159 (final words of section 27) "see the specification of the
- |NounDomain| library routine in \S A9." Reference should be
- to \S A7.
-
- after the "megalook" exercise and before "The rest of this
- section...": insert the passage
-
- * Formally, scope determines what you can talk about, which usually
- * means what you can see. But what can you touch? Suppose a locked
- * chest is inside a sealed glass cabinet. The Inform parser will
- * allow the command ``unlock chest with key'' and generate the
- * appropriate action, |Unlock chest key|, because the chest is in
- * scope, so the command at least makes sense.
-
- * But it's impossible to carry out, because the player can't reach
- * through the solid glass. So the library's routine for handling the
- * |Unlock| action needs to enforce this. The library does this
- * using a stricter rule called ``touchability''. The rule is that
- * you can touch anything in scope unless there's a closed container
- * between you and it. This applies either if you're in the container,
- * or if it is.
-
- * Some purely visual actions don't require touchability -- |Examine|
- * or |LookUnder|, for instance. But most actions are tactile, and
- * so will many actions created by designers. If you want to make
- * your own action routines enforce touchability, you can call the
- * library routine |ObjectIsUntouchable(obj)|. This either returns
- * |false| if there's no problem in touching |obj|, or returns |true|
- * and prints a suitable message (such as ``The solid glass cabinet
- * is in the way.''). Thus, the first line of many of the library's
- * action routines is:
- *
- * if (ObjectIsUntouchable(noun)) return;
- *
- * You can also call |ObjectIsUntouchable(obj, true)| to simply return
- * true or false, and print nothing, if you'd rather provide your
- * own failure message.
-
- p.162 "it should execute |InScope| and |ScopeWithin|" should read
- "it should execute |PlaceInScope| and |ScopeWithin|".
-
- p.164 Replace
-
- apply to all three pronouns ("it", "him" and "her")
-
- with
-
- apply to all pronouns (in English, "it", "him", "her" and "them")
-
- * Replace the bracketed clause in the next sentence,
- *
- * ('it', 'him' or 'her')
- *
- * with
- *
- * ('it', 'him', etc.)
-
- Delete the sentence:
-
- Note that the variables |itobj|, |himobj| and |herobj| hold
- the current settings of the pronouns.
-
- And add a new (normal) paragraph immediately after this point:
-
- You can find out the current setting of a pronoun using
- the library's |PronounValue| routine: for instance,
- |PronounValue('it')| would give the object which "it"
- currently refers to (possibly |nothing|). Similarly
- |SetPronoun('it', magic_ruby)| would set "it" to mean
- the magic ruby object. (When something like a magic ruby
- suddenly appears in the middle of a turn, players will
- habitually call it "it".) A better way to adjust the
- pronouns is to call |PronounNotice(magic_ruby)|, which
- sets whatever pronouns are appropriate. That is, it
- works out if the object is a thing or a person, of what
- number and gender, which pronouns apply to it in the parser's
- current language, and so on. In code predating Inform 6.1
- you may see variables called |itobj|, |himobj| and
- |herobj| holding the English pronoun values: these still
- work properly, but please use the modern system in
- new games.
-
- p.164 Replace
-
- 0 means the parser is intending not to include it, 1 means it
- intends not to.
-
- with
-
- 0 means the parser has decided against, 1 means it has decided
- in favour.
-
- In numbered lines 1 and 2 immediately following, replace "it" with
- "the object".
-
- p.165 (Yes, It's Infocom Nostalgia Pedantry Time!) Replace "and the
- original Infocom parser" with "and the parsers in most of the
- Infocom games".
-
- p.166 Opening line: for "Sorceror" read "Sorcerer".
-
- p.166 Replace the sentence beginning "Inform provides a small suite..."
- up to "...including the library files." with:
-
- Inform provides a small suite of debugging verbs,
- which will be added to any game compiled with the |-D| switch.
- If you prefer, you can include them manually by writing
-
- |Constant DEBUG;|
-
- somewhere in the program before the library files are included.
-
- p.166 Three additional lines for the table of debugging verbs.
- Add to the top of the list:
-
- |showobj <anything>|
-
- Insert after the "scope" line:
-
- |showverb <verb>|
-
- Insert after the "routines" line:
-
- |messages messages on messages off|
-
- p.167 Corresponding changes in the big paragraph describing these
- verbs. Insert a new first sentence:
-
- "showobj" is very informative about the current state of
- an object.
-
- After the "scope" sentence, add:
-
- "showverb" will display the grammar being used when the
- given verb is parsed.
-
- Before the "timers" sentence, add:
-
- It also describes all messages sent in the game, which is
- why it can also be written as "messages".
-
- p.167 Replace the two short paragraphs about Infix with the
- latest prevarication:
-
- * A source-level debugger for Inform, called Infix,
- * has been planned for some years, and may possibly be coming
- * to fruition soon.
-
- * (danger) For the benefit of such tools, Inform (if compiling
- * with the |-k| option set) produces a file of "debugging
- * information" (cross-references of the game file with the
- * source code), and anyone interested in writing an Inform
- * utility program may want to know the format of this file:
- * see the _Technical Manual_ for details.
-
- p.167 In the next paragraph replace "Zip is better here and" with
- "A Standard interpreter"
-
- p.168 References: delete the reference to David Wagner's "showobj".
-
- p.169 In the table of maximum sizes of games in different versions,
- the entry for V6 should read 512, not 576. (Not a typo but
- a reconsideration.)
-
- p.170 (passage on memory management) "restrictions" should read
- "restriction".
-
- p.170 (limit for function calls) Alter "(Or, in V3, at most 3.)"
- to "(Or, in V3 and V4, at most 3.)".
-
- p.170 (passage on Abbreviate) Replace "A good list of abbreviations
- can be found in the _Technical Manual_: basically," with
- "When choosing abbreviations,". Insert a new sentence to follow
- that one:
-
- Good choices include |" the "|, |"The"|, |", "|,
- |"and"|, |"you"|, |" a "|, |"ing"|, |" to"|.
-
- p.171 Delete the initial WARNING. (Support for V3 games is gradually
- being withdrawn, and this warning only puts people needlessly
- off.)
-
- p.174 (top) Delete the sentence "The author recommends that anyone
- using exotic assembly-language... on both."
-
- Replace the next sentence, "All three common interpreters are,
- in fact, pretty reliable." with:
-
- * Interpreters conforming to the Z-Machine Standard, usually
- * but not always derived from Frotz or Zip, are reliable and
- * widely available.
-
- p.175 (passage on buffer_mode) "This turns on (|flag=1|) or off
- (|flag=1|)...": the second time should be |flag=0|.
-
- p.177 For "Torbj@/orn Andersson", read "Torbj@:orn Andersson",
- * that is, replace the slash on the second "o" with a
- * diaresis (double-dot) accent.
-
- p.177 Replace the WARNING with the following:
-
- WARNING:
- Some of these features may not work well on obsolete interpreters
- which do not adhere to the Z-Machine Standard. Standard
- interpreters are widely available, but if seriously worried
- you can test whether your game is running on a good interpreter:
-
- |if (standard_interpreter == 0)|
- |{ print "This game must be played on an interpreter obeying the|
- | Z-Machine Standard.^";|
- | @quit;|
- |}|
-
- p.179 Table of operator precedences: in the line for level 11,
- on function calls, replace the text
-
- function call
-
- with
-
- function call on right hand side
-
- and add a new bottom line:
-
- 14 (...) binary left function call on left hand side
-
- p.183 In the syntax explanation: replace the 6 (the maximum number
- of tokens per line) with 31. At the end of the syntax paragraph
- insert the following new paragraph:
-
- A grammar line can optionally be followed by the word
- |reverse|. This signals that the action to be generated has
- two parameters, but which have been parsed in the wrong
- order and need to swapped over. (Note that a |topic| is
- not a parameter, and nor is a preposition.)
-
- p.183 Add a new token to the summary table, just before [special]:
-
- [topic] any text at all
-
- p.183 Add a new paragraph immediately after the summary table:
-
- Two or more literal words (only) can be written with slash
- signs |/| between them as alternatives. E.g., |"in"/"on"|
- matches either the word "in" or the word "on".
-
- p.185 Entry for the attribute |female|: replace with the following:
-
- This object has a feminine name. In games written in English,
- this makes her a female person, though in other languages it might
- be inanimate. The parser uses this information when considering
- pronouns like "her". (In English, anything |animate| is assumed
- to be male unless |female| or |neuter| is set.)
-
- Insert the following similar entry for new attribute |male|:
-
- This object has a masculine name. In games written in English,
- this makes him a male person, though in other languages it might
- be inanimate. The parser uses this information when considering
- pronouns like "him". (In English, anything |animate| is assumed
- to be male unless |female| or |neuter| is set.)
-
- And then for the new attribute |neuter|:
-
- This object's name is neither masculine nor feminine. (In
- English, anything without |animate| is assumed neuter, because
- only people and higher animals have gender. Anything |animate|
- is assumed male unless |female| or |neuter| is set. A
- robot, for instance, might be an |animate| object worth making
- |neuter|.)
-
- p.185 Insert the following entry for new attribute |pluralname|:
-
- This single object's name is in the plural. For instance, an
- object called "seedless grapes" should have |pluralname| set.
- The library will then use the pronoun "them" and the indefinite
- article "some" automatically.
-
- p.186 Insert a new property entry:
-
- articles Array of strings
-
- For objects: If given, these are the articles used with
- the object's name. (Provided for non-English languages
- where irregular nouns may have unusual vowel-contraction
- rules with articles: e.g. with French non-mute H.)
-
- p.187 Under |daemon|: remove the warning line "The same object
- cannot..."
-
- another new property entry:
-
- * inside_description String or routine
-
- * For objects: Printed as part or all of a room description
- * when the player is inside the given object, which must be
- * |enterable|.
-
- p.190 Insert a new property entry:
-
- short_name_indef Routine
-
- For objects: If set, this form of the short name is used
- when the name is prefaced by an indefinite article. (This
- is not useful in English-language games, but in other
- languages adjectival parts of names agree with the
- definiteness of the article.)
-
- p.190 Under |time_out|: remove the warning line "The same object
- cannot..."
-
- p.191 Add two new objects to the end of the list of special objects
- defined by the library:
-
- InformLibrary Represents the library. You never need to use
- it, but it might sometimes be the value of
- |sender| when a message is received.
- InformParser Represents the parser.
-
- list of library routines: add
-
- * |ObjectIsUntouchable(obj,flag)|
- * Determines whether any solid barrier (that is, any |container| that
- * is not |open|) lies between the player and |obj|. If |flag| is set,
- * this routine never prints anything; otherwise it prints a message
- * like ``You can't, because ... is in the way.'' if any barrier is
- * found. Returns |true| if a barrier is found, |false| if not.
-
- p.200 (in rule 5) "Properties, attributes and classes must..." should
- read "Attributes and classes must...".
-
- p.202 Lexicon definition of "common property": replace the first sentence
- with:
-
- Any _property_ set by the _class_ |Object| is passed on to every
- _object_, and is called a ``common property'': for example,
- |description|. All others are _individual properties_. New
- properties can be declared as common with the |Property| directive.
-
- and delete the final bracketed sentence about the library's
- properties, which doesn't belong in a definition.
-
-
- Part II -- Alterations to exercise solutions
- =================================
-
- In each case the full revised text of the solution is given. Some are
- hardly altered but others are expanded (e.g. exercise 35) or simplified
- (exercise 54). However, the prefix #r$ has been deleted in the
- few cases when they occur without giving details (see exercises 79, 80).
- This matters too little to fuss over.
-
- Exercise 4:
- ----------
- Put any validation rules desired into the |GamePreRoutine|.
- For example, the following will filter out any stray |Drop| actions for
- unheld objects:
-
- [ GamePreRoutine;
- if (action==Drop && noun notin player)
- "You aren't holding ", (the) noun, ".";
- rfalse;
- ];
- ----------
-
- Exercise 9:
- ----------
- Object -> bag "toothed bag"
- with name "toothed" "bag",
- description "A capacious bag with a toothed mouth.",
- before
- [; LetGo: "The bag defiantly bites itself
- shut on your hand until you desist.";
- Close: "The bag resists all attempts to close it.";
- ],
- after
- [; Receive:
- "The bag wriggles hideously as it swallows ",
- (the) noun, ".";
- ],
- has container open;
- ----------
-
- Exercise 14:
- ----------
- Object -> cage "iron cage"
- with name "iron" "cage" "bars" "barred" "iron-barred",
- when_open
- "An iron-barred cage, large enough to stoop over inside,
- looms ominously here.",
- when_closed "The iron cage is closed.",
- inside_description "You stare out through the bars.",
- has enterable container openable open transparent static;
- ----------
-
- Exercise 17:
- ----------
- Object -> bible "black Tyndale Bible"
- with name "bible" "black" "book",
- initial "A black Bible rests on a spread-eagle lectern.",
- description "A splendid foot-high Bible, which must have survived
- the burnings of 1520.",
- before
- [ w x; Consult:
- wn = consult_from; w = NextWord();
- switch(w)
- { 'matthew': x="Gospel of St Matthew";
- 'mark': x="Gospel of St Mark";
- 'luke': x="Gospel of St Luke";
- 'john': x="Gospel of St John";
- default: "There are only the four Gospels.";
- }
- if (consult_words==1)
- "You read the ", (string) x, " right through.";
- w = TryNumber(wn);
- if (w==-1000)
- "I was expecting a chapter number in the ",
- (string) x, ".";
- "Chapter ", (number) w, " of the ", (string) x,
- " is too sacred for you to understand now.";
- ];
- ----------
-
- Exercise 19:
- ----------
- Add the following lines, after the inclusion of |Grammar|:
-
- [ SayInsteadSub; "[To talk to someone, please type ~someone, something~
- or else ~ask someone about something~.]"; ];
- Extend "answer" replace * topic -> SayInstead;
- Extend "tell" replace * topic -> SayInstead;
-
- A slight snag is that this will throw out ``nigel,
- tell me about the grunfeld defence'' (which the library will normally
- convert to an |Ask| action, but can't if the grammar for ``tell'' is
- missing). To avoid this, you could (instead of making the above
- directives) |Replace| the |TellSub| routine (see \S 21)
- by the |SayInsteadSub| one.
- ----------
-
- Exercise 21:
- ----------
- Object -> Charlotte "Charlotte"
- with name "charlotte" "charlie" "chas",
- grammar
- [; give self ~general;
- wn=verb_wordnum;
- if (NextWord()=='simon' && NextWord()=='says')
- { give self general;
- verb_wordnum=verb_wordnum+2;
- }
- ],
- orders
- [ i; if (self hasnt general) "Charlotte sticks her tongue out.";
- WaveHands: "Charlotte waves energetically.";
- default: "~Don't know how,~ says Charlotte.";
- ],
- initial "Charlotte wants to play Simon Says.",
- has animate female proper;
-
- (The variable |i| isn't needed yet, but will be used by the
- code added in the answer to the next exercise.)
- ----------
-
- Exercise 27:
- ----------
- Object replicator "replicator"
- with name "replicator",
- grammar [; return 'rc,'; ],
- orders
- [; Give:
- if (noun in self)
- "The replicator serves up a cup of ",
- (name) noun, " which you drink eagerly.";
- "~That is not something I can replicate.~";
- default: "The replicator is unable to oblige.";
- ],
- life
- [; Ask, Answer, Tell: "The replicator has no conversation skill.";
- ],
- has talkable;
- Object -> "Earl Grey tea" with name "earl" "grey" "tea";
- Object -> "Aldebaran brandy" with name "aldebaran" "brandy";
- Object -> "distilled water" with name "distilled" "water";
- ...
- Verb "rc," * held -> Give;
-
- The point to note here is that the [held] token means `held by the
- replicator' here, as the |actor| is the replicator, so this is a neat way of
- getting a `one of the following phrases' token into the grammar.
- ----------
-
- Exercise 28:
- ----------
- This is similar to the previous exercises. One creates an attribute called
- |crewmember| and gives it to the crew objects: the |orders| property is
-
- orders
- [; Examine:
- if (parent(noun)==0)
- "~", (name) noun,
- " is no longer aboard this demonstration game.~";
- "~", (name) noun, " is in ", (name) parent(noun), ".~";
- default: "The computer's only really good for locating the crew.";
- ],
-
- and the |grammar| simply returns |'stc,'| which is defined as
-
- [ Crew i;
- switch(scope_stage)
- { 1: rfalse;
- 2: objectloop (i has crewmember) PlaceInScope(i); rtrue;
- }
- ];
- Verb "stc," * "where" "is" scope=Crew -> Examine;
-
- An interesting point is that the scope routine doesn't need to do anything
- at stage 3 (usually used for printing out errors) because the normal
- error-message printing system is never reached. Something like ``computer,
- where is Comminder Doto'' causes a |##NotUnderstood| order.
- ----------
-
- Exercise 29:
- ----------
- Object Zen "Zen" Flight_Deck
- with name "zen" "flight" "computer",
- initial "Square lights flicker unpredictably across a hexagonal
- fascia on one wall, indicating that Zen is on-line.",
- grammar [; return 'zen,'; ],
- orders
- [; Show: "The main screen shows a starfield,
- turning through ", noun, " degrees.";
- Go: "~Confirmed.~ The ship turns to a new bearing.";
- SetTo: if (noun==0) "~Confirmed.~ The ship comes to a stop.";
- if (noun>12) print_ret "~Standard by ", (number) noun,
- " exceeds design tolerances.~";
- print_ret "~Confirmed.~ The ship's engines step to
- standard by ", (number) noun, ".";
- Take: if (noun~=force_wall) "~Please clarify.~";
- "~Force wall raised.~";
- Drop: if (noun~=blasters) "~Please clarify.~";
- "~Battle-computers on line.
- Neutron blasters cleared for firing.~";
- default: "~Language banks unable to decode.~";
- ],
- has talkable proper static;
- Object -> force_wall "force wall" with name "force" "wall" "shields";
- Object -> blasters "neutron blasters" with name "neutron" "blasters";
- ...
- Verb "zen," * "scan" number "orbital" -> Show
- * "set" "course" "for" Planet -> Go
- * "speed" "standard" "by" number -> SetTo
- * "raise" held -> Take
- * "clear" held "for" "firing" -> Drop;
-
- Dealing with |Ask|, |Answer| and |Tell| are left to the reader.
- ----------
-
- Exercise 33:
- ----------
- We could solve this using a daemon, but for the
- sake of demonstrating a feature of |thedark| we won't.
- In |Initialise|, write |thedark.initial = GoMothGo;|
- and add the routine:
-
- [ GoMothGo;
- if (moth in player)
- { remove moth;
- "As your eyes try to adjust, you feel a ticklish sensation
- and hear a tiny fluttering sound.";
- }
- ];
- ----------
-
- Exercise 34:
- ----------
- This is a crude implementation, for brevity (the real Zork
- thief has an enormous stock of attached messages). A |life| routine
- is omitted, and of course this particular thief steals
- nothing. See `The Thief' for a much fuller, annotated
- implementation.
- \beginlines
- Object -> thief "thief"
- with name "thief" "gentleman" "mahu" "modo",
- each_turn "^The thief growls menacingly.",
- daemon
- [ i p j n k;
- if (random(3)~=1) rfalse;
- p=parent(thief);
- objectloop (i in compass)
- { j=p.(i.door_dir);
- if (j ofclass Object && j hasnt door) n++;
- }
- if (n==0) rfalse;
- k=random(n); n=0;
- objectloop (i in compass)
- { j=p.(i.door_dir);
- if (j ofclass Object && j hasnt door) n++;
- if (n==k)
- { move self to j;
- if (p==location) "^The thief stalks away!";
- if (j==location) "^The thief stalks in!";
- rfalse;
- }
- }
- ],
- has animate;
- \endlines
- (Not forgetting to |StartDaemon(thief)| at some point, for instance
- in the game's |Initialise| routine.) So the thief walks at random but
- never via doors, bridges and the like (because these may be locked
- or have rules attached); it's only a first approximation, and in a
- good game one should occasionally see the thief do something
- surprising, such as open a secret door. As for the |name|, note
- that `The Prince of darkness is a gentleman. Modo he's called, and Mahu'
- (William Shakespeare, _King Lear_ III iv.)
- ----------
-
- Exercise 35:
- ----------
- We shall use a new property called |weight| and decide that
- any object which doesn't provide any particular weight will weigh
- 10 units. Clearly, an object which contains other objects will
- carry their weight too, so:
-
- [ WeightOf obj t i;
- if (obj provides weight) t = obj.weight; else t = 10;
- objectloop (i in obj) t = t + WeightOf(i);
- return t;
- ];
-
- Once every turn we shall check how much the player is carrying
- and adjust a measure of the player's fatigue accordingly. There
- are many ways we could choose to calculate this: for the sake of
- example we'll define two constants:
-
- Constant CARRYING_STRENGTH = 500;
- Constant HEAVINESS_THRESHOLD = 100;
-
- Initially the player's strength will be the maximum possible,
- which we'll set to 500. Each turn the amount of weight being
- carried is substracted from this, but 100 is also added on
- (without exceeding the maximum value). So if the player carries
- more than 100 units, then her strength declines, but by dropping
- things to get the weight below 100 she can allow it to recover.
- If she drops absolutely everything, her entire strength will
- recuperate in at most 5 turns. Exhaustion sets in if her strength
- reaches 0, and at this point she is forced to drop something,
- which gives her strength a slight boost. Anyway, here's an
- implementation of all this:
-
- Object weight_monitor
- with players_strength,
- warning_level 5,
- activate
- [; self.players_strength = CARRYING_STRENGTH; StartDaemon(self);
- ],
- daemon
- [ w s b bw;
- if (location ~= Weights_Room) { StopDaemon(self); return; }
- s = self.players_strength
- - WeightOf(player) + HEAVINESS_THRESHOLD;
- if (s<0) s=0; if (s>CARRYING_STRENGTH) s=CARRYING_STRENGTH;
- self.players_strength = s;
- if (s==0)
- { bw=-1;
- objectloop(b in player)
- if (WeightOf(b) > bw) { bw = WeightOf(b); w=b; }
- self.players_strength = self.players_strength + bw;
- print "^Exhausted with carrying so much, you decide
- to discard ", (the) w, ": "; <<Drop w>>;
- }
- w=s/100; if (w==self.warning_level) return;
- self.warning_level = w;
- switch(w)
- { 3: "^You are feeling a little tired.";
- 2: "^You possessions are weighing you down.";
- 1: "^Carrying so much weight is wearing you out.";
- 0: "^You're nearly exhausted enough to drop everything
- at an inconvenient moment.";
- }
- ];
-
- Notice that items are actually dropped with |Drop| actions: one of them
- might be, say, a wild boar, which would bolt away into the forest when
- released. The daemon tries to drop the heaviest item. (Obviously a little
- improvement would be needed if the game contained, say, an un-droppable
- but very heavy ball and chain.) Finally, of course, at some point
- the weight monitor has to be sent an |activate| message to get things
- going.
- ----------
-
- Exercise 44:
- ----------
- The common man's _wayhel_ was a lowly mouse. Since we think
- much more highly of the player:
-
- Object hog "Warthog" Caldera
- with name "wart" "hog" "warthog", description "Muddy and grunting.",
- number 0,
- initial "A warthog snuffles and grunts about in the ash.",
- orders
- [; Go, Look, Examine, Eat, Smell, Taste, Touch: rfalse;
- default: "Warthogs can't do anything as tricky as that!";
- ],
- has animate proper;
-
- and we just |ChangePlayer(warthog);|. Note that the same |orders|
- routine applies to the player-as-human typing "warthog, listen"
- as to the player-as-warthog typing just "listen".
- ----------
-
- Exercise 48:
- ----------
- See the _Inform Translator's Manual_. One must provide
- a new grammar file (generating the same actions but from different
- syntax), tables showing how pronouns, possessives and articles work
- in the new language, a sheaf of translated library messages and
- so on. But it can be done.
- ----------
-
- Exercise 54:
- ----------
- Class Coin
- with name "coin" "coins//p",
- description "A round unstamped disc, presumably local currency.",
- list_together "coins",
- plural
- [; print (string) (self.&name)-->0;
- if (~~(listing_together ofclass Coin)) print " coins";
- ],
- short_name
- [; if (listing_together ofclass Coin)
- { print (string) (self.&name)-->0; rtrue; }
- ],
- article
- [; if (listing_together ofclass Coin) print "one"; else print "a";
- ];
- Class Gold_coin class Coin with name "gold";
- Class Silver_coin class Coin with name "silver";
- Class Bronze_coin class Coin with name "bronze";
- SilverCoin -> "silver coin";
- ... and so on
- ----------
-
- Exercise 55:
- ----------
- Firstly, a printing rule to print the state of coins. Coin-objects
- will have a property called |way_up| which is always either 1 or 2:
-
- [ Face x; if (x.way_up==1) print "Heads"; else print "Tails"; ];
-
- There are two kinds of coin but we'll implement them with three
- classes: |Coin| and two sub-categories, |GoldCoin| and |SilverCoin|.
- Since the coins only join up into trigrams when present in groups
- of three, we need a routine to detect this:
-
- [ CoinsTogether cla i x y;
- objectloop (i ofclass cla)
- { x=parent(i);
- if (y==0) y=x; else { if (x~=y) return 0; }
- }
- return y;
- ];
-
- Thus |CoinsTogether(cla)| decides whether all objects of class |cla|
- are in the same place. (|cla| will always be either |GoldCoin| or
- |SilverCoin|.) We must now write the class definitions:
-
- Class Coin
- with name "coin" "coins//p",
- way_up 1, article "the",
- after
- [; Drop, PutOn:
- self.way_up = random(2); print (Face) self;
- if (CoinsTogether(self.which_class))
- { print ". The ";
- if (self.which_class == GoldCoin)
- print "gold"; else print "silver";
- " trigram is now ", (Trigram) self.which_class;
- }
- ".";
- ];
- [ CoinLT k i c;
- if (inventory_stage==1)
- { if (self.which_class == GoldCoin)
- print "the gold"; else print "the silver";
- print " coins ";
- k=CoinsTogether(self.which_class);
- if (k==location || k has supporter)
- { objectloop (i ofclass self.which_class)
- { print (name) i;
- switch(++c)
- { 1: print ", "; 2: print " and ";
- 3: print " (showing the trigram ",
- (Trigram) self.which_class, ")";
- }
- }
- rtrue;
- }
- if (~~(c_style & ENGLISH_BIT)) c_style = c_style + ENGLISH_BIT;
- if (~~(c_style & NOARTICLE_BIT)) c_style = c_style + NOARTICLE_BIT;
- if (c_style & NEWLINE_BIT) c_style = c_style - NEWLINE_BIT;
- if (c_style & INDENT_BIT) c_style = c_style - INDENT_BIT;
- }
- rfalse;
- ];
- Class GoldCoin class Coin
- with name "gold", which_class GoldCoin,
- list_together [; return CoinLT(); ];
- Class SilverCoin class Coin
- with name "silver", which_class SilverCoin,
- list_together [; return CoinLT(); ];
-
- (There are two unusual points here. Firstly, the |CoinsLT| routine
- is not simply given as the common |list_together| value in the |coin|
- class since, if it were, all six coins would be grouped together:
- we want two groups of three, so the gold and silver coins have to have
- different |list_together| values. Secondly, if a trigram is together
- and on the floor, it is not good enough to simply append text like
- "showing Tails, Heads, Heads (change)" at |inventory_stage| 2 since the
- coins may be listed in a funny order: for example, in the order snake,
- robin, bison. In that event, the order the coins are listed in
- doesn't correspond to the order their values are listed in, which is
- misleading. So instead |CoinsLT| takes over entirely at
- |inventory_stage| 1 and prints out the list of three itself, returning
- true to stop the list from being printed out by the library as well.)
- To resume: whenever coins are listed together, they are grouped
- into gold and silver. Whenever trigrams are visible they are to be
- described by either |Trigram(GoldClass)| or |Trigram(SilverClass)|:
-
- Array gold_trigrams --> "fortune" "change" "river flowing" "chance"
- "immutability" "six stones in a circle"
- "grace" "divine assistance";
- Array silver_trigrams --> "happiness" "sadness" "ambition" "grief"
- "glory" "charm" "sweetness of nature"
- "the countenance of the Hooded Man";
- [ Trigram cla i k state;
- objectloop (i ofclass cla)
- { print (Face) i; if (k++<2) print ","; print " ";
- state=state*2 + (i.way_up-1);
- }
- if (cla == GoldCoin) i=gold_trigrams; else i=silver_trigrams;
- print "(", (string) i-->state, ")";
- ];
-
- (These interpretations of the coins are quite bogus.) Finally
- we have to make the six actual coins:
-
- GoldCoin -> "goat" with name "goat";
- GoldCoin -> "deer" with name "deer";
- GoldCoin -> "chicken" with name "chicken";
- SilverCoin -> "robin" with name "robin";
- SilverCoin -> "snake" with name "snake";
- SilverCoin -> "bison" with name "bison";
- ----------
-
- Exercise 57:
- ----------
- Object -> "/?%?/ (the artiste formally known as Princess)"
- with name "princess" "artiste" "formally" "known" "as",
- short_name
- [; if (self hasnt general) { print "Princess"; rtrue; }
- ],
- react_before
- [; Listen: print_ret (name) self, " sings a soft siren song.";
- ],
- initial
- [; print_ret (name) self, " is singing softly.";
- ],
- parse_name
- [ x n; if (self hasnt general)
- { if (NextWord()=='princess') return 1;
- return 0;
- }
- x=WordAddress(wn);
- if ( x->0 == '/' && x->1 == '?' && x->2 == '%'
- && x->3 == '?' && x->4 == '/')
- { while (wn<=parse->1 && WordAddress(wn++)<x+5) n++;
- return n;
- }
- return -1;
- ],
- life
- [; Kiss: give self general; self.life = NULL;
- "In a fairy-tale transformation, the Princess
- steps back and astonishes the world by announcing
- that she will henceforth be known as ~/?%?/~.";
- ],
- has animate proper female;
- ----------
-
- Exercise 61:
- ----------
- [ ParseNoun;
- if (WordLength(wn)==1 && WordAddress(wn)->0 == '#') return 1;
- return -1;
- ----------
-
- Exercise 62:
- ----------
- [ ParseNoun;
- if (WordLength(wn)==1 && WordAddress(wn)->0 == '#') return 1;
- if (WordLength(wn)==1 && WordAddress(wn)->0 == '*')
- { parser_action = ##PluralFound; return 1; }
- return -1;
- ];
- ----------
-
- Exercise 65:
- ----------
- Because the parser might go on to reject the line it's working on:
- for instance, if the player typed "shazam splurge" then the message
- "Shazam!" followed by a parser complaint will be somewhat unedifying.
- ----------
-
- Exercise 66:
- ----------
- The scheme will work like this: any room that ought to have a name
- should have a |place_name| property set to a dictionary word;
- say, the Bedquilt cave could be called |'bedquilt'|. Clearly
- you should only be allowed to type this from adjacent rooms.
- So we'll implement the following: you can only move by name to
- those rooms listed in the current room's |to_places| property.
- For instance, the Soft Room might have |to_places| set to
-
- to_places Bedquilt Slab_Room Twopit_Room;
-
- Now the code: if the player's verb is not otherwise understood,
- we'll check it to see if it's a place name of a nearby room,
- and if so store that room's object number in |goto_room|, converting
- the verb to |'go#room'| (which we'll deal with below).
-
- Global goto_room;
- [ UnknownVerb word p i;
- p = location.&to_places; if (p==0) rfalse;
- for (i=0:(2*i)<location.#to_places:i++)
- if (word==(p-->i).place_name)
- { goto_room = p-->i; return 'go#room';
- }
- rfalse;
- ];
- [ PrintVerb word;
- if (word=='go#room')
- { print "go to ", (name) goto_room; rtrue; }
- rfalse;
- ];
-
- (The supplied |PrintVerb| is icing on the cake: so the parser can
- say something like "I only understood you as far as wanting to go to
- Bedquilt." in reply to, say, "bedquilt the nugget".) It remains
- only to create the dummy verb:
-
- [ GoRoomSub;
- if (goto_room hasnt visited) "But you have never been there.";
- PlayerTo(goto_room);
- ];
- Verb "go#room" * -> GoRoom;
-
- Note that if you don't know the way, you can't go there! A purist might
- prefer instead to not recognise the name of an unvisited room, back at
- the |UnknownVerb| stage, to avoid the player being able to deduce names
- of nearby rooms from this `error message'.
- ----------
-
- Exercise 71:
- ----------
- Again, the first question is how to store the
- number dialled: in this case, into a |string| array. The token is:
-
- Constant MAX_PHONE_LENGTH = 30;
- Array dialled_number string MAX_PHONE_LENGTH;
- [ PhoneNumber f a l ch pp i;
- pp=1; if (NextWordStopped()==-1) return 0;
- do
- { a=WordAddress(wn-1); l=WordLength(wn-1);
- for (i=0:i<l:i++)
- { ch=a->i;
- if (ch<'0' || ch>'9')
- { if (ch~='-') { f=1; if (i~=0) return -1; } }
- else
- { if (pp<MAX_PHONE_LENGTH)
- dialled_number->(pp++)=ch-'0';
- }
- }
- } until (f==1 || NextWordStopped()==-1);
- if (pp==1) return -1;
- dialled_number->0 = pp-1;
- return 0;
- ];
-
- To demonstrate this in use,
-
- [ DialPhoneSub i;
- print "You dialled <";
- for (i=1:i<=dialled_number->0:i++) print dialled_number->i;
- ">";
- ];
- Verb "dial" * PhoneNumber -> DialPhone;
- ----------
-
- Exercise 81:
- ----------
- A slight refinement of such a "purloin" verb is already defined
- in the library (if the constant |DEBUG| is defined), so there's no need.
- But here's how it could be done:
-
- [ Anything i;
- if (scope_stage==1) rfalse;
- if (scope_stage==2)
- { objectloop (i ofclass Object) PlaceInScope(i); rtrue; }
- "No such in game.";
- ];
-
- (This disallows multiple matches for efficiency reasons -- the parser has
- enough work to do with such a huge scope definition as it is.) Now
- the token |scope=Anything| will match anything at all, even things like
- the abstract concept of `east'.
-
-
- Part III -- Alterations to library messages (section A9)
- ============================================
-
- The text is altered throughout, so here is an entirely new version of
- section A9.
-
-
- Answer "There is no reply."
- Ask "There is no reply."
- Attack "Violence isn't the answer to this one."
- Blow "You can't usefully blow that/those."
- Burn "This dangerous act would achieve little."
- Buy "Nothing is on sale."
- Climb "I don't think much is to be achieved by that."
- Close 1. "That's/They're not something you can close."
- 2. "That's/They're already closed."
- 3. "You close <x1>."
- Consult "You discover nothing of interest in <x1>."
- Cut "Cutting that/those up would achieve little."
- Dig "Digging would achieve nothing here."
- Disrobe 1. "You're not wearing that/those."
- 2. "You take off <x1>."
- Drink "There's nothing suitable to drink here."
- Drop 1. "The <x1> is/are already here."
- 2. "You haven't got that/those."
- 3. "(first taking <x1> off)"
- 4. "Dropped."
- Eat 1. "That's/They're plainly inedible."
- 2. "You eat <x1>. Not bad."
- EmptyT 1. <x1> " can't contain things."
- 2. <x1> " is/are closed."
- <x1> " is/are empty already."
- Enter 1. "But you're already on/in <x1>."
- 2. "That's/They're not something you can enter."
- 3. "You can't get into the closed <x1>."
- 4. "You can only get into something freestanding."
- 5. "You get onto/into <x1>."
- Examine 1. "Darkness, noun. An absence of light to see by."
- 2. "You see nothing special about <x1>."
- 3. "<x1> is/are currently switched on/off."
- Exit 1. "But you aren't in anything at the moment."
- 2. "You can't get out of the closed <x1>."
- 3. "You get off/out of <x1>."
- Fill "But there's no water here to carry."
- FullScore 1. "The score is/was made up as follows:|^|"
- 2. "finding sundry items"
- 3. "visiting various places"
- 4. "total (out of |MAX_SCORE|)"
- GetOff "But you aren't on <x1> at the moment."
- Give 1. "You aren't holding <x1>."
- 2. "You juggle <x1> for a while, but don't achieve much."
- 3. "<x1> doesn't/don't seem interested."
- Go 1. "You'll have to get off/out of <x1> first."
- 2. "You can't go that way."
- 3. "You are unable to climb <x1>."
- 4. "You are unable to descend <x1>."
- 5. "You can't, since <x1> is/are in the way."
- 6. "You can't, since <x1> leads nowhere."
- Insert 1. "You need to be holding <x1> before you
- can put it/them into something else."
- 2. "That/Those can't contain things."
- 3. "<x1> is/are closed."
- 4. "You'll need to take it/them off first."
- 5. "You can't put something inside itself."
- 6. "(first taking it/them off)|^|"
- 7. "There is no more room in <x1>."
- 8. "Done."
- 9. "You put <x1> into <second>."
- Inv 1. "You are carrying nothing."
- 2. "You are carrying"
- Jump "You jump on the spot, fruitlessly."
- JumpOver "You would achieve nothing by this."
- Kiss "Keep your mind on the game."
- Listen "You hear nothing unexpected."
- LMode1 " is now in its normal ~brief~ printing mode, which gives
- long descriptions of places never before visited and short
- descriptions otherwise."
- LMode2 " is now in its ~verbose~ mode, which always gives long
- descriptions of locations (even if you've been there before)."
- LMode3 " is now in its ~superbrief~ mode, which always gives short
- descriptions of locations (even if you haven't been there before)."
- Lock 1. "That doesn't/They don't seem to be something you can lock."
- 2. "That's/They're locked at the moment."
- 3. "First you'll have to close <x1>."
- 4. "That doesn't/Those don't seem to fit the lock."
- 5. "You lock <x1>."
- Look 1. " (on <x1>)"
- 2. " (in <x1>)"
- 3. " (as <x1>)"
- 4. "|^|On <x1> is/are <list of children>"
- 5. "[On/In <x1>] you/You can also see <list of children> [here]."
- 6. "[On/In <x1>] you/You can see <list of children> [here]."
- LookUnder 1. "But it's dark."
- "You find nothing of interest."
- Mild "Quite."
- ListMiscellany 1. " (providing light)"
- 2. " (which is/are closed)"
- 3. " (closed and providing light)"
- 4. " (which is/are empty)"
- 5. " (empty and providing light)"
- 6. " (which is/are closed and empty)"
- 7. " (closed, empty and providing light)"
- 8. " (providing light and being worn"
- 9. " (providing light"
- 10. " (being worn"
- 11. " (which is/are "
- 12. "open"
- 13. "open but empty"
- 14. "closed"
- 15. "closed and locked"
- 16. " and empty"
- 17. " (which is/are empty)"
- 18. " containing "
- 19. " (on "
- 20. ", on top of "
- 21. " (in "
- 22. ", inside "
- Miscellany 1. "(considering the first sixteen objects only)|^|"
- 2. "Nothing to do!"
- 3. " You have died "
- 4. " You have won "
- 5. (The RESTART/RESTORE/QUIT and possibly FULL
- and AMUSING query, printed after the game is over.)
- 6. "[Your interpreter does not provide undo. Sorry!]"
- 7. "Undo failed. [Not all interpreters provide it.]"
- 8. "Please give one of the answers above."
- 9. "|^|It is now pitch dark in here!"
- 10. "I beg your pardon?"
- 11. "[You can't "undo" what hasn't been done!]"
- 12. "[Can't "undo" twice in succession. Sorry!]"
- 13. "[Previous turn undone.]"
- 14. "Sorry, that can't be corrected."
- 15. "Think nothing of it."
- 16. ""Oops" can only correct a single word."
- 17. "It is pitch dark, and you can't see a thing."
- 18. "yourself" (the short name of the |selfobj| object)
- 19. "As good-looking as ever."
- 20. "To repeat a command like "frog, jump", just say
- "again", not "frog, again"."
- 21. "You can hardly repeat that."
- 22. "You can't begin with a comma."
- 23. "You seem to want to talk to someone, but I can't see whom."
- 24. "You can't talk to <x1>."
- 25. "To talk to someone, try "someone, hello" or some such."
- 26. "(first taking <|not_holding|>)"
- 27. "I didn't understand that sentence."
- 28. "I only understood you as far as wanting to "
- 29. "I didn't understand that number."
- 30. "You can't see any such thing."
- 31. "You seem to have said too little!"
- 32. "You aren't holding that!"
- 33. "You can't use multiple objects with that verb."
- 34. "You can only use multiple objects once on a line."
- 35. "I'm not sure what "<pronoun>" refers to."
- 36. "You excepted something not included anyway!"
- 37. "You can only do that to something animate."
- 38. "That's not a verb I recognise."
- 39. "That's not something you need to refer to in the
- course of this game."
- 40. "You can't see "<pronoun>" (<value>) at the moment."
- 41. "I didn't understand the way that finished."
- 42. "None/only <x1> of those is/are available."
- 43. "Nothing to do!"
- 44. "There are none at all available!"
- 45. "Who do you mean, "
- 46. "Which do you mean, "
- 47. "Sorry, you can only have one item here. Which exactly?"
- 48. "Whom do you want [<actor>] to <command>?"
- 49. "What do you want [<actor>] to <command>?"
- 50. "Your score has just gone up/down by <x1> point/points."
- 51. "(Since something dramatic has happened, your list of
- commands has been cut short.)"
- 52. "Type a number from 1 to <x1>, 0 to redisplay or press ENTER."
- 53. "[Please press SPACE.]"
- No see \bf Yes
- NotifyOff "Score notification off."
- NotifyOn "Score notification on."
- Objects 1. "Objects you have handled:|^|"
- 2. "None."
- 3. " (worn)"
- 4. " (held)"
- 5. " (given away)"
- 6. " (in <x1>)" [without article]
- 7. " (in <x1>)" [with article]
- 8. " (inside <x1>)"
- 9. " (on <x1>)"
- 10. " (lost)"
- Open 1. "That's/They're not something you can open."
- 2. "It seems/They seem to be locked."
- 3. "That's/They're already open."
- 4. "You open <x1>, revealing <list of children of x1>"
- 5. "You open <x1>."
- Order "<x1> has/have better things to do."
- Places "You have visited: "
- Pray "Nothing practical results from your prayer."
- Prompt 1. "|^>|"
- Pronouns 1. "At the moment, "
- 2. "means "
- 3. "is unset "
- 4. "no pronouns are known to the game."
- Pull 1. "It is/Those are fixed in place."
- 2. "You are unable to."
- 3. "Nothing obvious happens."
- 4. "That would be less than courteous."
- Push see \bf Pull
- PushDir 1. "Is that the best you can think of?"
- 2. "That's not a direction."
- 3. "Not that way you can't."
- PutOn 1. "You need to be holding <x1> before you
- can put it/them on top of something else."
- 2. "You can't put something on top of itself."
- 3. "Putting things on <x1> would achieve nothing."
- 4. "You lack the dexterity."
- 5. "(first taking it/them off)|^|"
- 6. "There is no more room on <x1>."
- 7. "Done."
- 8. "You put <x1> on <second>."
- Quit 1. "Please answer yes or no."
- 2. "Are you sure you want to quit? "
- Remove 1. "It is/They are unfortunately closed."
- 2. "But it isn't/they aren't there now."
- 3. "Removed."
- Restart 1. "Are you sure you want to restart? "
- 2. "Failed."
- Restore 1. "Restore failed."
- 2. "Ok."
- Rub "You achieve nothing by this."
- Save 1. "Save failed."
- 2. "Ok."
- Score "You have so far/In that game you scored <score> out of
- a possible |MAX_SCORE|, in <turns> turn/turns"
- ScriptOn 1. "Transcripting is already on."
- 2. "Start of a transcript of"
- ScriptOff 1. "Transcripting is already off."
- 2. "|^|End of transcript."
- Search 1. "But it's dark."
- 2. "There is nothing on <x1>."
- 3. "On <x1> is/are <list of children>."
- 4. "You find nothing of interest."
- 5. "You can't see inside, since <x1> is/are closed."
- 6. "<x1> is/are empty."
- 7. "In <x1> is/are <list of children>."
- Set "No, you can't set that/those."
- SetTo "No, you can't set that/those to anything."
- Show 1. "You aren't holding <x1>."
- 2. "<x1> is/are unimpressed."
- Sing "Your singing is abominable."
- Sleep "You aren't feeling especially drowsy."
- Smell "You smell nothing unexpected."
- Sorry "Oh, don't apologise."
- Squeeze 1. "Keep your hands to yourself."
- 2. "You achieve nothing by this."
- Strong "Real adventurers do not use such language."
- Swim "There's not enough water to swim in."
- Swing "There's nothing sensible to swing here."
- SwitchOff 1. "That's/They're not something you can switch."
- 2. "That's/They're already off."
- 3. "You switch <x1> off."
- SwitchOn 1. "That's/They're not something you can switch."
- 2. "That's/They're already on."
- 3. "You switch <x1> on."
- Take 1. "Taken."
- 2. "You are always self-possessed."
- 3. "I don't suppose <x1> would care for that."
- 4. "You'd have to get off/out of <x1> first."
- 5. "You already have that/those."
- 6. "That seems/Those seem to belong to <x1>."
- 7. "That seems/Those seem to be a part of <x1>."
- 8. "That isn't/Those aren't available."
- 9. "<x1> isn't/aren't open."
- 10. "That's/They're hardly portable."
- 11. "That's/They're fixed in place."
- 12. "You're carrying too many things already."
- 13. "(putting <x1> into |SACK_OBJECT| to make room)"
- Taste "You taste nothing unexpected."
- Tell 1. "You talk to yourself a while."
- 2. "This provokes no reaction."
- Touch 1. "Keep your hands to yourself!"
- 2. "You feel nothing unexpected."
- 3. "If you think that'll help."
- Think "What a good idea."
- Tie "You would achieve nothing by this."
- ThrowAt 1. "Futile."
- 2. "You lack the nerve when it comes to the crucial moment."
- Turn see \bf Pull
- Unlock 1. "That doesn't/They don't seem to be something you can unlock."
- 2. "It's/They're unlocked at the moment."
- 3. "That doesn't/Those don't seem to fit the lock."
- 4. "You unlock <x1>."
- VagueGo "You'll have to say which compass direction to go in."
- Verify 1. "The game file has verified as intact."
- 2. "The game file did not verify properly, and may be corrupted
- (or you may be running it on a very primitive interpreter which
- is unable properly to perform the test)."
- Wait "Time passes."
- Wake "The dreadful truth is, this is not a dream."
- WakeOther "That seems unnecessary."
- Wave 1. "But you aren't holding that/those."
- 2. "You look ridiculous waving <x1>."
- WaveHands "You wave, feeling foolish."
- Wear 1. "You can't wear that/those!"
- 2. "You're not holding that/those!"
- 3. "You're already wearing that/those!"
- 4. "You put on <x1>."
- Yes "That was a rhetorical question."
-
-